package pl.wr.math.utils;

/**
 * @version 1.0
 * @author wieslaw.rodak
 * 
 */
public class Util {

	/**
	 * @param x
	 *            int value
	 * @param y
	 *            int value
	 * @return The greatest common divisor
	 */
	public static int gcd(final int x, final int y) {

		if (0 == y) {
			return x;
		}
		return gcd(y, (x % y));

	}

	/**
	 * @param x
	 *            int value
	 * @param y
	 *            int value
	 * @return The greatest common factor
	 */
	public static int gcf(final int x, final int y) {

		return (x * y) / gcd(x, y);
	}

	/**
	 * @param x
	 *            long value
	 * @param y
	 *            long value
	 * @return The greatest common divisor
	 */
	public static long gcd(final long x, final long y) {

		if (0 == y) {
			return x;
		}
		return gcd(y, (x % y));

	}

	/**
	 * @param x
	 *            long value
	 * @param y
	 *            long value
	 * @return The greatest common factor
	 */
	public static long gcf(final long x, final long y) {

		return (x * y) / gcd(x, y);
	}

	/**
	 * Convert a number in decimal fraction notation to array that contains
	 * common fraction (numerator, denominator, exponent)
	 * 
	 * @param d
	 *            - the decimal fraction
	 * @return the common fraction: [0] - numerator, [1] - denominator, [2] -
	 *         exponent of number
	 */
	public static long[] decimalToCommon(final double d) {

		final double[] fragmentation = fragmentationDouble(d);

		double decimal = fragmentation[0];

		final double factor = Math.pow(10, Double.toString(fragmentation[0])
				.length() - 2);
		decimal *= factor;

		long numerator = (long) decimal;
		long denominator = 1;

		denominator *= factor;

		final long nwd = Util.gcd(numerator, denominator);
		numerator /= nwd;
		denominator /= nwd;

		final long[] ret = {numerator, denominator, (long) fragmentation[1]};

		return ret;
	}

	/**
	 * Convert a number in exponential notation to array that contains number
	 * and exponent.
	 * 
	 * @param d
	 *            - Number in exponential notation
	 * @return - [0] - number without exponent, [1] - exponent of number
	 */
	public static double[] fragmentationDouble(final double d) {
		final String str = Double.toString(d);
		final int e = str.indexOf('E');
		String number = null;
		String exponent = "0";
		if (e > 0) {
			number = str.substring(0, e);
			exponent = str.substring(e + 1);
		} else {
			number = str;
		}

		final double[] ret = {new Double(number), new Double(exponent)};
		return ret;
	}

}
